<template>
  <el-row>
    <div class="block">
      <el-date-picker v-model="value2" type="datetimerange" :shortcuts="shortcuts" range-separator="To" start-placeholder="起始日期" end-placeholder="结束日期"/>
    </div>
    <div class="block">
      <el-select v-model="value3" placeholder="选择区域" style="width: 240px">
        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
    </div>
    <div class="block">
      <el-radio-group v-model="timeView" @change="updateView">
        <el-radio :label="1" :class="{ active: timeView === 1 }" border>按件</el-radio>
        <el-radio :label="2" :class="{ active: timeView === 2 }" border>按小时</el-radio>
        <el-radio :label="3" :class="{ active: timeView === 3 }" border>按天</el-radio>
      </el-radio-group>
    </div>

  </el-row>
  <div>
    <el-card><div ref="chart" style="height: 370px; width: 1300px"></div></el-card>
    <el-card>
      <div ref="chart2" style="height: 300px; width: 1300px"></div>
    </el-card>
    <el-card>
      <el-button @click="exportToExcel">导出为 Excel</el-button>
      <el-table :data="pagedTableData1" border style="width: 90%">
    <el-table-column prop="时间" label="时间" width="300"></el-table-column>
    <el-table-column prop="设备节拍" label="设备节拍" width="300"></el-table-column>
    <el-table-column prop="人工节拍" label="人工节拍" width="300"></el-table-column>
    <el-table-column prop="工位" label="工位" width="300"></el-table-column>
  </el-table>
  <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[5, 10, 30, 50]"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="totalItems"
      />
    </el-card>
    <el-card>
      <el-table :data="tableData" border style="width: 90%">
        <el-table-column prop="assetnum" label="工位" width="150" />
        <el-table-column prop="actual_cycle" label="设备节拍" width="150" />
        <!-- 新增：设备加工时间目标编辑列 -->
        <el-table-column label="设备加工时间目标" width="200">
          <template #default="{ row }">
            <el-input
              v-model.number="row.equipment_target_time"
              size="small"
              @change="updateTarget(row)"
            />
          </template>
        </el-table-column>
        <!-- 新增：人工推拉时间目标编辑列 -->
        <el-table-column label="人工推拉时间目标" width="200">
          <template #default="{ row }">
            <el-input
              v-model.number="row.push_pull_target_time"
              size="small"
              @change="updateTarget(row)"
            />
          </template>
        </el-table-column>
        <!-- 新增：CT目标（计算列，只读） -->
        <el-table-column prop="ct_target" label="CT目标" width="150" />
        <el-table-column prop="compensation" label="补偿节拍" width="200">
          <template #default="{ row }">
            <el-input
              v-model.number="row.compensation"
              size="small"
              @change="applyCompensation(row)"
            />
          </template>
        </el-table-column>
        <el-table-column prop="accumulated_compensation" label="累计补偿节拍" width="200" />
      </el-table>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch, toRef, toRefs } from "vue";
import * as echarts from "echarts"; //引入echarts核心模块
import axios from "axios"; //引入echarts核心模块
import { useRouter } from "vue-router";
import XLSX from 'xlsx'; // 导入 xlsx
import { saveAs } from 'file-saver';


let lastPointId = null;
const value2 = ref([]);

const shortcuts = [
  {
    text: "近1周",
    value: () => {
      const end = new Date();
      const start = new Date();
      start.setDate(start.getDate() - 7);
      return [start, end];
    },
  },
  {
    text: "近2周",
    value: () => {
      const end = new Date();
      const start = new Date();
      start.setDate(start.getDate() - 14);
      return [start, end];
    },
  },
  {
    text: "近1月",
    value: () => {
      const end = new Date();
      const start = new Date();
      start.setMonth(start.getMonth() - 1);
      return [start, end];
    },
  },
];
const chart = ref(); 
const chart2 = ref();
const chartInstance2 = ref(null);
const series_data = ref();
const series_data1 = ref();
const series_data2 = ref();
const timeView = ref(1); 
const tableData1 = ref([]);
const currentPage = ref(1);
const pageSize = ref(5);
const totalItems = ref(0);
const averagedData = ref([]);
const compensationValues = ref(new Map());
const excludedPoints = [
'CBM1CONVY_1','CBM1CONVY_2','CBM1CONVY_3','CBM2CONVY_1','CBM2CONVY_2','CBM2CONVY_3',
];
const excludedPointsauto = [
  '1010','1050','1060','1090','1100','1170','1180','1220','1230','1250','1261','1260','1280','1300','1330','1340','1360','1380','1390','1410','1430','4010','4050',
  '2010','2020','2030','2060','2070','2170','2185','2190','2230','2240','2250','2255','2280','2290','2300','2310','2340','2360','2390','2400','2410','2430','2460','2480','2490','5010','5020',
  '3010','305A','3120','1053'
];
const excludedPointsmanual = [
  '1020','1030','1055','1080','1110','1120','1160','1190','121A','121C','1240','1275','1270','1290','1310','1320','135A','135B','1370','140A','140B','4020',
  '205A','205B','2080','2090','2110','213B','2160','2180','2210','2220','2320','2350','2370','2470',
 ,'3020','303A','303B','3040','3080','3090','3100','3110','1058'
];

const handleSizeChange = (val: number) => {
  pageSize.value = val;
  updatePagedData();
};
const handleCurrentChange = (val: number) => {
  currentPage.value = val;
  updatePagedData();
};

const updatePagedData = () => {
  const startIndex = (currentPage.value - 1) * pageSize.value;
  const endIndex = startIndex + pageSize.value;
  pagedTableData1.value = tableData1.value.slice(startIndex, endIndex);
};

const pagedTableData1 = ref([]);

const initChart = async () => {
  if (chart.value == null) {
    return;
  }

  echarts.dispose(chart.value);
  const myChart = echarts.init(chart.value);
  myChart.setOption({});
  
  const isCBM = value3.value === "CBM1" || value3.value === "CBM2";
  
  let option = {
    tooltip: {
      trigger: "axis",
      formatter: function (params) {
        let result = "";
        const pointId = params[0].name;
        const seriesInfo = {};

        for (let i = 0; i < params.length; i++) {
          const param = params[i];

          if (param.name === pointId) {
            const seriesName = param.seriesName;
            const value = param.value;
            if (!seriesInfo[seriesName]) {
              seriesInfo[seriesName] = value;
            }
          }
        }
        result += pointId + "<br/>";
        for (const [seriesName, value] of Object.entries(seriesInfo)) {
          result += seriesName + ": " + value + "<br/>";
        }
        const maxVal = maxFieldValMap.get(pointId);
        const minVal = minFieldValMap.get(pointId);
        const over = overTargetCountMap.get(pointId);
        const overCT = overCTCountMap.get(pointId);
        const lessCT = lessCTCountMap.get(pointId);
        const conformityRate = conformityRateMap.get(pointId);
        result += "最大节拍: " + maxVal + "<br/>";
        result += "最小节拍: " + minVal + "<br/>";
        result += "超节拍次数：" + over + "<br/>";
        result += "超+5%CT数：" + overCT + "<br/>";
        result += "超-5%CT数：" + lessCT + "<br/>";
        result += "节拍符合率: " + (conformityRate * 100).toFixed(2) + "%<br/>";

        return result;
      },
    },
    legend: {
      data: isCBM 
        ? ["平均设备加工时间","平均人工推拉时间","设备加工时间目标","CT目标","FTQ","内控线"]
        : ["平均设备加工时间","平均人工推拉时间","设备加工时间目标","CT目标","FTQ"],
      orient: "horizontal", 
      left: "right", 
      top: "top", 
      itemGap: 10,
      selected: {
        '内控线': false
      }
    },
    title: {
      text: `${value3Label.value} 周期节拍分析`,
      left: "left",
      subtext: "s",
      textStyle: {
        color: "black", 
      },
      subtextStyle: {
        fontWeight: "bold",
      },
    },
    xAxis: {
      type: "category",
      data: series_data1.value,
      axisLabel: {
        rotate: 45 
      }
    },
    yAxis: [
      {
        type: 'value',
        name: '节拍',
        position: 'left',
        axisLabel: {
          formatter: '{value}'
        }
      },
      {
        type: 'value',
        name: 'Rate (%)',
        position: 'right',
        axisLabel: {
          formatter: '{value} %'
        },
        max: 100,
      }
    ],
    series: [
      {
        name: "平均设备加工时间",
        type: "bar",
        stack: 'total',
        data: series_data.value,
        yAxisIndex: 0,
        itemStyle: {
          normal: {
            color: function(params) {
              const targetCycle = targetCycleMap.get(series_data1.value[params.dataIndex]) || 0;
              const value = series_data.value[params.dataIndex];
              return value > targetCycle ? 'red' : '#00ff00';
            }
          }
        },
      },
      {
        name: "平均人工推拉时间",
        type: "bar",
        stack: 'total',
        data: series_data2.value,
        yAxisIndex: 0,
        itemStyle: {
          normal: {
            color: function(params) {
              const averageEquipmentTime = series_data.value[params.dataIndex];
              const averageUnloadTime = series_data2.value[params.dataIndex];
              const ctTarget = CTtargetCycleMap.get(series_data1.value[params.dataIndex]) || 0;
              return (averageEquipmentTime + averageUnloadTime) > ctTarget ? 'orange' : 'lightblue';
            }
          }
        },
      },
      {
        name: "设备加工时间目标",
        type: "line",
        step: "start",
        yAxisIndex: 0,
        symbol: 'circle', 
        data: targetSeriesData.value, 
        color: 'blue', 
        lineStyle: {
          color: 'blue', 
          width: 1.4,
        },
      },
      {
        name: "CT目标",
        type: "line",
        step: "start",
        yAxisIndex: 0,
        symbol: 'circle', 
        data: targetSeriesData1.value, 
        color: 'purple', 
        lineStyle: {
          color: 'purple', 
          width: 1.4,
        },
      },
      {
        name: "FTQ",
        type: "line",
        data: [], 
        symbol: 'circle',
        yAxisIndex: 1,
        color: '#b6a2de', 
        lineStyle: {
          color: '#b6a2de',
          width: 1.4,
          type: 'solid'
        },
      },
      ...(isCBM ? [{
        name: "内控线",
        type: "line",
        step: "start",
        yAxisIndex: 0,
        symbol: 'circle',
        data: series_data1.value.map(assetnum => {
          const ctTarget = targetCycleMap.get(assetnum) || 0;
          return ctTarget <= 100 ? ctTarget - 7 : ctTarget - 4;
        }),
        color: 'red',
        lineStyle: {
          color: 'red',
          width: 1.4,
          type: 'dashed'
        },
        show: false
      }] : [])
    ],
  };
  
  const ftqRateData = [];
  series_data1.value.forEach(pointId => {
    let ftqRate = 0;
    let longestMatchLength = 0;

    for (const [station, rate] of ftqRateMap) {
      if (pointId.includes(station) && station.length > longestMatchLength) {
        ftqRate = rate;
        longestMatchLength = station.length;
      }
    }
    ftqRateData.push(ftqRate > 0 ? ftqRate * 100 : null);
  });

  option.series.find(s => s.name === "FTQ").data = ftqRateData;
  
  myChart.on('legendselectchanged', function(params) {
    if (params.name === '内控线') {
      const option = myChart.getOption();
      const seriesIndex = option.series.findIndex(s => s.name === '内控线');
      if (seriesIndex !== -1) {
        option.series[seriesIndex].show = params.selected['内控线'];
        myChart.setOption(option);
      }
    }
  });

  myChart.on('click', (params) => {
    console.log('Clicked:', params);
    const assetnum = params.name; 
    useShowDataInHtmlForTable(assetnum);
    const row = tableData.value.find(item => item.assetnum === assetnum);
    if (row) {
      const targetCycle = row.equipment_target_time;
      const cttargetCycle = row.ct_target;
      
      initChart2(
        chart2BaseData.value,
        assetnum,
        targetCycle,
        cttargetCycle,
        chart2BaseData.value.map(item => item.unloadtime)
      );
    }
  });
  
  myChart.setOption(option);
};
const initChart2 = (seriesData, assetnum, targetCycle, cttargetCycle, loadingcycle) => {
  if (chartInstance2.value == null) {
    return;
  }

  echarts.dispose(chartInstance2.value);
  const myChart2 = echarts.init(chartInstance2.value);
  myChart2.setOption({});

  const isCBM = value3.value === "CBM1" || value3.value === "CBM2";

  let option = {
    title: {
      text: `${assetnum} 节拍统计`,
      left: "left",
      subtext: "s",
      textStyle: {
        color: "black", 
      },
      subtextStyle: {
        fontWeight: "bold",
      },
    },
    legend: {
      data: isCBM 
        ? ["设备加工时间","人工推拉时间","设备加工时间目标","CT目标","内控线"]
        : ["设备加工时间","人工推拉时间","设备加工时间目标","CT目标"],
      orient: "horizontal",
      left: "right",
      top: "top",
      itemGap: 10,
      selected: {
        '内控线': false
      }
    },
    tooltip: {
      trigger: "axis",
      formatter: function (params) {
        let result = "";
        for (let i = 0; i < params.length; i++) {
          const param = params[i];
          if (i === 0) {
            result += param.name + "<br/>";
          }
          result += param.seriesName + ": " + param.value + "<br/>";
        }
        return result;
      },
    },
    xAxis: {
      type: "category",
      data: seriesData.map(item => item.name),
    },
    dataZoom: [
      {
        type: "slider",
        start: 0,
        end: 100,
      },
      {
        type: "inside",
        start: 90,
        end: 100,
      },
    ],
    yAxis: {
      type: "value",
    },
    series: [
      {
        name: "设备加工时间",
        type: "bar",
        stack: "total",
        data: seriesData.map(item => {
          const value = parseFloat(item.value).toFixed(2);
          return {
            value: value,
            itemStyle: {
              color: value > targetCycle ? 'red' : '#00ff00'
            }
          };
        }),
      },
      {
        name: "人工推拉时间",
        type: "bar",
        stack: 'total',
        data: seriesData.map(item => {
          const totalValue = parseFloat(item.value) + parseFloat(item.unloadtime);
          return {
            value: parseFloat(item.unloadtime),
            itemStyle: {
              color: totalValue > cttargetCycle ? 'orange' : '#ADD8E6'
            }
          };
        })
      },
      {
        name: "设备加工时间目标",
        type: "line",
        data: Array(seriesData.length).fill(targetCycle), 
        symbol: 'circle',
        color: 'blue',
        lineStyle: {
          color: 'blue',
          width: 1.4,
        }
      },
      {
        name: "CT目标",
        type: "line",
        data: Array(seriesData.length).fill(cttargetCycle),
        symbol: 'circle',
        color: 'purple',
        lineStyle: {
          color: 'purple',
          width: 1.4,
        }
      },

      ...(isCBM ? [{
        name: "内控线",
        type: "line",
        data: Array(seriesData.length).fill(
          targetCycle <= 100 ? targetCycle - 7 : targetCycle - 4
        ),
        symbol: 'circle',
        color: 'red',
        lineStyle: {
          color: 'red',
          width: 1.4,
          type: 'dashed'
        },
        show: false
      }] : [])
    ],
  };


  myChart2.on('legendselectchanged', function(params) {
    if (params.name === '内控线') {
      const option = myChart2.getOption();
      const seriesIndex = option.series.findIndex(s => s.name === '内控线');
      if (seriesIndex !== -1) {
        option.series[seriesIndex].show = params.selected['内控线'];
        myChart2.setOption(option);
      }
    }
  });

  myChart2.setOption(option);
};
onMounted(() => {
  const todayStart = new Date();
  todayStart.setHours(0, 0, 0, 0); 
  const todayEnd = new Date(); 
  value2.value = [todayStart, todayEnd];

  use_show_data_in_html2();
  chartInstance2.value = chart2.value;
  updatePagedData(); 
  useShowDataInHtmlForTable("OP10A");
});

const value3 = ref("CBM1");
const value3Label = ref("缸体M1");
const router = useRouter();
const options = [
  { value: "CBM1", label: "缸体M1" },
  { value: "CBM2", label: "缸体M2" },
  { value: "CHM1", label: "缸盖M1" },
  { value: "CHM2", label: "缸盖M2" },
  { value: "CS", label: "曲轴M1" },
];

watch(value3, (newValue) => {
  const selectedOption = options.find(option => option.value === newValue);
  if (selectedOption) {
    value3Label.value = selectedOption.label;
  }
});

function formatDate(d: string) {
  var date = new Date(d);
  var YY = date.getFullYear() + "-";
  var MM = (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-";
  var DD = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
  var hh = (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":";
  var mm = (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":";
  var ss = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
  return YY + MM + DD + " " + hh + mm + ss;
}

var construct_url = "";
watch([value2, value3], () => {
  const start_time = formatDate(value2.value[0]);
  const end_time = formatDate(value2.value[1]);
  const newvalue3 = value3.value; 


  construct_url = `http://10.64.35.32:8000/postgresql_data_api/get_DataCycletime_data/?` +
                  `start_time=${start_time}&` +
                  `end_time=${end_time}&` +
                  `assetnum=${newvalue3}&` +
                  `page_size=100001`;
  console.log('url',construct_url)
  use_show_data_in_html2();
});

  const maxFieldValMap = new Map();
  const minFieldValMap = new Map();
  const targetCycleMap = new Map();
  const CTtargetCycleMap = new Map();
  const ftqRateMap = new Map();
  const overTargetCountMap = new Map();
  const overCTCountMap = new Map();
  const lessCTCountMap = new Map();
  const conformityRateMap = new Map();  
  const targetSeriesData = ref([]);
  const targetSeriesData1 = ref([]);
  const equipmentTargetTimeMap = new Map();
  const pushPullTargetTimeMap = new Map();

  const fetchTargetCycleData = async () => {
  try {
    const page = value3.value;
    const url = `http://10.64.35.32:8000/manufacture_analysis/get_ms_cycle_data/?station=${page}&page_size=100`;
    const response = await axios.get(url);
    const data = response.data;

    if (!Array.isArray(data)) {
      throw new Error('Expected an array of objects');
    }

    targetCycleMap.clear();
    CTtargetCycleMap.clear();

    data.forEach(item => {
      const { station, equipment_target_time, push_pull_target_time } = item;
      const pointId = station.includes('OP') ? station.substring(station.indexOf('OP')) : station;
      targetCycleMap.set(pointId, equipment_target_time);
      CTtargetCycleMap.set(pointId, equipment_target_time + push_pull_target_time);
    });

  } catch (error) {
    console.error("Failed to fetch target cycle data:", error);
  }
};

const fetchPartCountData = async () => {
  try {
    const start_time = formatDate(value2.value[0]);
  const end_time = formatDate(value2.value[1]);
    const assetnum = value3.value;
    const url = `http://10.64.35.32:8000/postgresql_data_api/get_DataPartcount_data/?start_time=${start_time}&end_time=${end_time}&assetnum=${assetnum}&page_size=10000`;
    const response = await axios.get(url);
    const data = response.data;
    ftqRateMap.clear();
    const ftqRateByStation = new Map(); 

    data.forEach(item => {
      const opSuffix = 'OP' + item.assetnum.split('OP')[1]; 
      let goodCount = 0;
      let totalCount = 0;

      if (item.counttype === 'Good') {
        goodCount ++;
      }
      totalCount ++;

      if (ftqRateByStation.has(opSuffix)) {
        const [existingGoodCount, existingTotalCount] = ftqRateByStation.get(opSuffix);
        ftqRateByStation.set(opSuffix, [existingGoodCount + goodCount, existingTotalCount + totalCount]);
      } else {
        ftqRateByStation.set(opSuffix, [goodCount, totalCount]);
      }
    });

    ftqRateByStation.forEach((counts, station) => {
      const [goodCount, totalCount] = counts;
      const ftqRate = totalCount ? goodCount / totalCount : 0;
      ftqRateMap.set(station, ftqRate);
    });
  } catch (error) {
    console.error("Failed to fetch part count data:", error);
  }
};

const use_show_data_in_html2 = async () => {
  await fetchPartCountData();
  await fetchTargetCycleData();

  const response = await axios.get(construct_url);
  let data = response.data;
  data = data.map(item => {
    const assetnum = item.assetnum;
    let dataValue = parseFloat(item.data);
    
    if ((value3.value === "CBM1" || value3.value === "CBM2") && 
        (assetnum.includes("OP150") || assetnum.includes("OP230"))) {
      dataValue = dataValue / 100;
    }
    
    return {
      ...item,
      data: dataValue.toString() 
    };
  });
  data = data.filter(item => {
    const dataValue = parseFloat(item.data); 
    return !isNaN(dataValue) && dataValue >= 30 && dataValue <= 200;
  });
  if (value3.value === "CS") {
    data = data.filter(item => {
      const assetnum = item.assetnum;
      if (assetnum.includes("OP130") || assetnum.includes("OP140")) {
        const dataValue = parseFloat(item.data); 
        const totalValue = dataValue + parseFloat(item.unloadtime || 0);
        return !isNaN(totalValue) && totalValue >= 40 && totalValue <= 50;
      }
      return true;
    });
  }
  if (value3.value === "CBM1" || value3.value === "CBM2") {
    data = data.filter(item => {
      const assetnum = item.assetnum;
      if (assetnum.includes("OP140") || assetnum.includes("OP210") || assetnum.includes("OP230")) {
        const dataValue = parseFloat(item.data); 
        const totalValue = dataValue + parseFloat(item.unloadtime || 0);
        return !isNaN(totalValue) && totalValue >= 40 && totalValue <= 100;
      }
      return true;
    });
  }
  const sumFieldValMap = new Map();
  const countMap = new Map();
  const unloadtimeMap = new Map();
  const totalunLoadtimeMap = new Map();

  data.forEach(item => {
    const assetnum = item.assetnum;
    const data = parseFloat(item.data);
    const unloadtime = item.unloadtime;
    const totalunLoadtime = item.unloadtime;

    if (excludedPoints.includes(assetnum)) {
      return;
    }
    
    let opSubstring;
    if (assetnum.includes("OP")) {
      opSubstring = assetnum.substring(assetnum.indexOf("OP"));
    } else {
      opSubstring = assetnum; 
    }
    
    if (!sumFieldValMap.has(opSubstring)) {
      sumFieldValMap.set(opSubstring, 0);
      countMap.set(opSubstring, 0);
      maxFieldValMap.set(opSubstring, data+unloadtime);
      minFieldValMap.set(opSubstring, data+unloadtime);
      overTargetCountMap.set(opSubstring, 0);
      overCTCountMap.set(opSubstring, 0);
      lessCTCountMap.set(opSubstring, 0);
      unloadtimeMap.set(opSubstring, unloadtime);
      totalunLoadtimeMap.set(opSubstring, totalunLoadtime);
    } else {
      maxFieldValMap.set(opSubstring, Math.max(maxFieldValMap.get(opSubstring), data+unloadtime));
      minFieldValMap.set(opSubstring, Math.min(minFieldValMap.get(opSubstring), data+unloadtime));
      unloadtimeMap.set(opSubstring, unloadtime);
      totalunLoadtimeMap.set(opSubstring, totalunLoadtimeMap.get(opSubstring) + totalunLoadtime);
    }

    sumFieldValMap.set(opSubstring, sumFieldValMap.get(opSubstring) + data);
    countMap.set(opSubstring, countMap.get(opSubstring) + 1);
    overCTCountMap.forEach((overCTCount, key) => {
      const lessCTCount = lessCTCountMap.get(key) || 0;
      const totalCount = countMap.get(key);
      const numerator = overCTCount + lessCTCount;
      const denominator = totalCount;
      const conformityRate = 1 - (numerator / denominator);
      conformityRateMap.set(key, conformityRate);
    });
    const targetCycle = targetCycleMap.get(opSubstring) || 0;
    if (data + unloadtime > targetCycle ) {
      overTargetCountMap.set(opSubstring, overTargetCountMap.get(opSubstring) + 1);
    }
    if (data + unloadtime > targetCycle * 1.05) {
      overCTCountMap.set(opSubstring, overCTCountMap.get(opSubstring) + 1);
    }
    if (data + unloadtime < targetCycle * 0.95) {
      lessCTCountMap.set(opSubstring, lessCTCountMap.get(opSubstring) + 1);
    }
  });
    
  const averagedData = Array.from(sumFieldValMap.entries())
    .sort((a, b) => {
      const opSubstringA = a[0].substring(a[0].indexOf("OP"));
      const opSubstringB = b[0].substring(b[0].indexOf("OP"));
      const numbersA = opSubstringA.match(/\d+/g);
      const numbersB = opSubstringB.match(/\d+/g);
      
      for (let i = 0; i < Math.min(numbersA.length, numbersB.length); i++) {
        if (numbersA[i] !== numbersB[i]) {
          return numbersA[i] - numbersB[i];
        }
      }
      
      return numbersA.length - numbersB.length;
    })
    .map(([assetnum, totalFieldVal]) => {
      const count = countMap.get(assetnum);
      const avgFieldVal = totalFieldVal / count;
      const totalunLoadtime = totalunLoadtimeMap.get(assetnum);
      const unloadtime = unloadtimeMap.get(assetnum);
      const avgunloadtime = totalunLoadtime / count;
      return { assetnum: assetnum, data: parseFloat((avgFieldVal).toFixed(2)), unloadtime: parseFloat((avgunloadtime).toFixed(2)) };
    });



  series_data1.value = averagedData.map(dataItem => dataItem.assetnum);
  series_data.value = averagedData.map(dataItem => dataItem.data);
  series_data2.value = averagedData.map(dataItem => dataItem.unloadtime);
  targetSeriesData.value = averagedData.map(dataItem => {
    const targetCycle = targetCycleMap.get(dataItem.assetnum) || 0;
    return targetCycle;
  });
  targetSeriesData1.value = averagedData.map(dataItem => {
    const targetCycle = CTtargetCycleMap.get(dataItem.assetnum) || 0;
    return targetCycle;
  });

  initChart();

  const initialData = series_data1.value.map((assetnum, index) => {

    const equipment_target_time = equipmentTargetTimeMap.get(assetnum) || targetCycleMap.get(assetnum) || 0;
    const push_pull_target_time = pushPullTargetTimeMap.get(assetnum) || 
                                 (CTtargetCycleMap.get(assetnum) || 0) - (targetCycleMap.get(assetnum) || 0);
    
    return {
      assetnum: assetnum,
      actual_cycle: series_data.value[index],
      equipment_target_time: equipment_target_time,
      push_pull_target_time: push_pull_target_time,
      ct_target: equipment_target_time + push_pull_target_time, 
      compensation: 0,
      accumulated_compensation: 0
    };
  });
  
  tableData.value = initialData;
};


const updateTarget = (row) => {

  equipmentTargetTimeMap.set(row.assetnum, row.equipment_target_time);
  pushPullTargetTimeMap.set(row.assetnum, row.push_pull_target_time);
  

  row.ct_target = row.equipment_target_time + row.push_pull_target_time;
  

  targetCycleMap.set(row.assetnum, row.equipment_target_time);
  CTtargetCycleMap.set(row.assetnum, row.ct_target);
  
  targetSeriesData.value = series_data1.value.map(assetnum => 
    targetCycleMap.get(assetnum) || 0
  );
  targetSeriesData1.value = series_data1.value.map(assetnum => 
    CTtargetCycleMap.get(assetnum) || 0
  );

  initChart();

  if (lastPointId && chart2BaseData.value) {
    const targetCycle = row.equipment_target_time;
    const cttargetCycle = row.ct_target;
    
    initChart2(
      chart2BaseData.value, 
      lastPointId, 
      targetCycle, 
      cttargetCycle, 
      chart2BaseData.value.map(item => item.unloadtime)
    );
  }
};

const tableData = ref([]);

const applyCompensation = (row) => {
  const compensation = parseFloat(row.compensation);
  if (!isNaN(compensation)) {
    row.accumulated_compensation += compensation;
    row.actual_cycle += compensation;
    updateChartData(row);
  }
};

const updateChartData = (row) => {
  const index = series_data1.value.findIndex(item => item === row.assetnum);
  if (index !== -1) {
    series_data.value[index] = row.actual_cycle;
    initChart();
  }
};
const asCycleData = ref(null);
const ctCycleData = ref(null);
const chart2BaseData = ref(null);
const useShowDataInHtmlForTable = async (assetnum) => {
  try {
    const start_time = formatDate(value2.value[0]);
    const end_time = formatDate(value2.value[1]);
    lastPointId = assetnum;
    const pointIdPart = value3.value.substring(0, 10);
    const page1 = value3.value;
    let apiEndpoint = "man_ana_sql_server/get_MS_LastCt_filter";
    
    if (pointIdPart.startsWith('MPTASCAS01') || 
        pointIdPart.startsWith('MPTAHCAH01') || 
        pointIdPart.startsWith('MPTACCAC01')) {
      apiEndpoint = "man_ana_sql_server/get_AS_LastCt_filter";
    }
    
    const newUrl = `http://10.64.35.32:8000/postgresql_data_api/get_DataCycletime_data/?` +
                   `start_time=${start_time}&end_time=${end_time}&` +
                   `assetnum=${page1 + assetnum}&page_size=100001`;
    console.log(newUrl);

    const response = await axios.get(newUrl);
    const filteredData = response.data
      .map(item => {
        let dataValue = parseFloat(item.data);

        if ((value3.value === "CBM1" || value3.value === "CBM2") && 
            (item.assetnum.includes("OP150") || item.assetnum.includes("OP230"))) {
          dataValue = dataValue / 100;
        }
        
        return {
          ...item,
          data: dataValue.toString()
        };
      })
      .filter(item => {
        const dataValue = parseFloat(item.data);
        const totalValue = dataValue + parseFloat(item.unloadtime || 0);
        
        if (isNaN(dataValue) || dataValue < 30 || dataValue > 200) {
          return false;
        }
        
        if (value3.value === "CS" && 
            (item.assetnum.includes("OP130") || item.assetnum.includes("OP140"))) {
          return totalValue >= 40 && totalValue <= 50;
        }
        
        if ((value3.value === "CBM1" || value3.value === "CBM2") && 
            (item.assetnum.includes("OP140") || item.assetnum.includes("OP210") || item.assetnum.includes("OP230"))) {
          return totalValue >= 40 && totalValue <= 100;
        }
        
        return true;
      });

    const targetCycle = targetCycleMap.get(assetnum) || 0;
    const cttargetCycle = CTtargetCycleMap.get(assetnum) || 0;

    tableData1.value = filteredData; 
    totalItems.value = tableData1.value.length;

    console.log(newUrl);

    const aggregatedData = aggregateData(filteredData, timeView.value);
    chart2BaseData.value = aggregatedData;
    await initChart2(aggregatedData, assetnum, targetCycle, cttargetCycle, filteredData.map(item => item.unloadtime));
    fillTableData(filteredData);
    updatePagedData();
  } catch (error) {
    console.error("获取数据时发生错误:", error);
  }
};

const fillTableData = (data) => {
  const sortedData = data.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
  tableData1.value = sortedData.map(item => ({
    时间: item.timestamp,
    设备节拍: parseFloat(item.data).toFixed(2), 
    人工节拍: item.unloadtime,
    工位: item.assetnum
  }));
};
const aggregateData = (data, timeView) => {
  switch (timeView) {
    case 1: 
      return data.map(dataItem => ({
        name: dataItem.timestamp,
        value: parseFloat(dataItem.data) ,
        unloadtime: dataItem.unloadtime
      }));
    case 2: 
      return aggregateByHour(data);
    case 3: 
      return aggregateByDay(data);
    default:
      return [];
  }
};

const aggregateByHour = (data) => {
  const hourlyData = {};
  data.forEach(item => {
    const timestamp = new Date(item.timestamp);
    const month = String(timestamp.getMonth() + 1).padStart(2, '0');
    const day = String(timestamp.getDate()).padStart(2, '0');
    const hour = String(timestamp.getHours()).padStart(2, '0');
    const nextHour = timestamp.getHours() === 23 ? "00" : String(parseInt(hour) + 1).padStart(2, '0');

    const key = `${month}-${day} ${hour}:00-${nextHour}:00`;
    
    if (!hourlyData[key]) {
      hourlyData[key] = {
        sum: 0,
        count: 0,
        sumunLoadtime: 0
      };
    }
    hourlyData[key].sum += parseFloat(item.data);
    hourlyData[key].count++;
    hourlyData[key].sumunLoadtime += parseFloat(item.unloadtime);
  });

  return Object.entries(hourlyData).map(([hour, { sum, count, sumunLoadtime }]) => ({
    name: hour,
    value: (sum / count ).toFixed(2),
    unloadtime: (sumunLoadtime / count).toFixed(2)
  }));
};

const aggregateByDay = (data) => {  
  const dailyData = {};

  data.forEach(item => {
    const timestamp = new Date(item.timestamp);
    const key = `${timestamp.getFullYear()}-${String(timestamp.getMonth() + 1).padStart(2, '0')}-${String(timestamp.getDate()).padStart(2, '0')}`;
    if (!dailyData[key]) {
      dailyData[key] = {
        sum: 0,
        count: 0,
        sumunLoadtime: 0
      };
    }
    dailyData[key].sum += parseFloat(item.data);
    dailyData[key].count++;
    dailyData[key].sumunLoadtime += parseFloat(item.unloadtime);
  });

  return Object.entries(dailyData).map(([day, { sum, count, sumunLoadtime }]) => ({
    name: day,
    value: (sum / count ).toFixed(2),
    unloadtime: (sumunLoadtime / count).toFixed(2)
  }));
};
watch(timeView, (newValue) => {
  if (lastPointId) {
    useShowDataInHtmlForTable(lastPointId);
  }
});

const exportToExcel = () => {
  import('xlsx').then(XLSX => {
    const worksheet = XLSX.utils.json_to_sheet(tableData1.value);
    const workbook = { Sheets: { data: worksheet }, SheetNames: ['data'] };
    const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
    const start = formatDate(value2.value[0]);
    const end = formatDate(value2.value[1]);
    const region = value3Label.value.replace(/\s/g, ''); 
    const station = lastPointId; 
    const filename = `${start}_${end}_${region}_${station}_节拍统计.xlsx`;

    saveAs(new Blob([excelBuffer], { type: 'application/octet-stream' }), filename);
  });
};

function handleRowClick(row) {
  if (!compensationValues.value.has(row.assetnum)) {
    compensationValues.value.set(row.assetnum, 0);
  }
}


</script>

<style scoped>
h3 {
  color: black;
}

.block {
  padding: 20px;
  text-align: center;
  flex: 1;
}
.block:last-child {
  border-right: none;
}
.block .demonstration {
  display: block;
  color: var(--el-text-color-secondary);
  font-size: 14px;
  margin-bottom: 20px;
}
.el-select .el-scrollbar__wrap {
  max-height: 50px !important;
  overflow-y: auto !important;
}

/* 基本样式 */
.el-radio {
  display: flex;
  align-items: center;
}

.el-radio__inner {
  width: 20px;
  height: 20px;
  border-radius: 50%; /* 圆形 */
}

/* 选中状态 */
.el-radio__input.is-checked .el-radio__inner {
  background-color: #409EFF; /* 选中时圆点颜色 */
  border-color: #409EFF; /* 选中时边框颜色 */
}

/* 选中状态的文字颜色 */
.el-radio__label {
  color: #333;
}

.el-radio__input.is-checked + .el-radio__label {
  color: #409EFF; /* 选中时文字颜色 */
}
</style>

